/*
 * see: http://lwn.net/Articles/22355/
*/

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/keyboard.h>
#define UP_PRESS		103
#define DOWN_PRESS		108
#define LEFT_PRESS		105
#define RIGHT_PRESS		106
#define PROCFS_MAX_SIZE 	2048

struct seq_file * proc_file;
void * v_var;
char UP[] = "up";
char DOWN[] = "down";
char LEFT[] = "left";
char RIGHT[] = "right";
char READY[] = "ready";
static struct proc_dir_entry *proc_entry;
int ret = 0;

char * command;

static int kinect_proc_show(struct seq_file *m, void *v ) {
	printk(KERN_INFO "proc_show command: %s\n", command);
  seq_printf(m, "%s\n", command);
  return 0;
}

static int kinect_proc_open(struct inode *inode, struct  file *file) {
  return single_open(file, kinect_proc_show, NULL);
}

static const struct file_operations kinect_proc_fops = {
  .owner = THIS_MODULE,
  .open = kinect_proc_open,
  .read = seq_read,
  .llseek = seq_lseek,
  .release = single_release
};

int kinect_notify(struct notifier_block *nblock, unsigned long code, void *_param) {
   struct keyboard_notifier_param *param = _param;
   struct vc_data *vc = param->vc;
   if (code == KBD_KEYCODE) {
      switch(param->value) {
	case UP_PRESS:
		command = UP;
		break;
	case DOWN_PRESS:
		command = DOWN;
  		break;
	case LEFT_PRESS:
	      command = LEFT;
	      break;
	case RIGHT_PRESS:
	      command = RIGHT;
	      break;
	default:
	      break;
      }
   }
   return ret;
}

static struct notifier_block nb = {
   .notifier_call = kinect_notify
};

static int __init kinect_proc_init(void) {
  command = READY;
  proc_entry = proc_create("kinect_proc", 0, NULL, &kinect_proc_fops);
  if (proc_entry == NULL)
    {
        ret = -1;
	printk(KERN_INFO "procEntry could not be created\n");
    }
    else
    {
      register_keyboard_notifier(&nb);
    }
  return ret;
}

static void __exit kinect_proc_exit(void) {
  remove_proc_entry("kinect_proc", NULL);
  unregister_keyboard_notifier(&nb);
}

MODULE_LICENSE("GPL");
module_init(kinect_proc_init);
module_exit(kinect_proc_exit);
